﻿package net.wangit.jdbc;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import net.wangit.jdbc.util.JDBCExceptionReporter;


public class BatchingBatcher extends BatcherImpl {

	private int batchSize;
	private int expectedRowCounts[];

	public BatchingBatcher(DBImplementor db) {
		super(db);
		expectedRowCounts = new int[getJDBCSettings().getBatchSize()];
	}

	public void addToBatch(int expectedRowCount) throws SQLException,
			JDBCException {
		PreparedStatement batchUpdate = getBatchStatement();
		batchUpdate.addBatch();
		expectedRowCounts[batchSize++] = expectedRowCount;
		if (batchSize == getJDBCSettings().getBatchSize())
			doExecuteBatch(batchUpdate);
	}

	protected void doExecuteBatch(PreparedStatement ps) throws SQLException,
			JDBCException {
		if (log.isDebugEnabled())
			log.debug((new StringBuilder("Executing batch size: ")).append(
					batchSize).toString());
		try {
			if (batchSize != 0) {
				int results[] = ps.executeBatch();
				for (int i = 0; i < batchSize; i++)
					if (results[i] == -2) {
						if (log.isDebugEnabled())
							log.debug((new StringBuilder(
									"success of batch update unknown: "))
									.append(i).toString());
					} else {
						if (results[i] == -3)
							throw new JDBCException((new StringBuilder(
									"Batch update failed: ")).append(i)
									.toString());
						if (expectedRowCounts[i] >= 0
								&& results[i] != expectedRowCounts[i])
							throw new JDBCException((new StringBuilder(
									"Batch update row count wrong: "))
									.append(i).toString());
					}

			}
		} catch (SQLException sqle) {
			JDBCExceptionReporter.logExceptions(sqle);
			throw sqle;
		} catch (RuntimeException re) {
			log.error("Exception executing batch: ", re);
			throw re;
		} finally {
			batchSize = 0;
		}
	}
}
